import json
import os
from PyQt5.QtWidgets import (
    QHBoxLayout,
    QVBoxLayout,
    QLabel,
    QStyledItemDelegate,
    QGridLayout,
    QHeaderView,
    QFileDialog,
    QComboBox,
    QFrame,
    QGroupBox,
    QAbstractItemView,
    QTableWidgetItem,
    QTableWidget,
    QSpacerItem,
    QSizePolicy,
    QWidget,
)
from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QObject, QEvent, QTimer
from PyQt5.QtGui import QPainter, QPen, QColor, QDoubleValidator
from PyQt5.Qt import Qt, QRect, QCompleter, QSortFilterProxyModel
from pydantic import BaseModel, Field, field_validator
import gui.controls.envs as envs
from ..basic_grid_component import BasicGridComponent

# import gui.controls.envs as envs
from ..dlg_model_params import DlgModelParams
from ..c_params_table import CParamsTable
from ..dlg_params import DlgParams
from ..utils import Utils
from ..custom_widget import LineEditFloat, LineEditStr, LineEditInt
from ..util import util_key_map
from .. import message_box as MBox

from enum import Enum


# 带搜索功能的下拉框
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)
        # self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # 添加筛选器模型来筛选匹配项
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)  # 大小写不敏感
        self.pFilterModel.setSourceModel(self.model())

        # 添加一个使用筛选器模型的QCompleter
        self.completer = QCompleter(self.pFilterModel, self)
        # 始终显示所有(过滤后的)补全结果
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)  # 不区分大小写
        self.setCompleter(self.completer)

        # Qcombobox编辑栏文本变化时对应的槽函数
        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    # 当在Qcompleter列表选中候，下拉框项目列表选择相应的子项目
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            # self.activated[str].emit(self.itemText(index))

    # 在模型更改时，更新过滤器和补全器的模型
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # 在模型列更改时，更新过滤器和补全器的模型列
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

    # 回应回车按钮事件
    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Enter & e.key() == Qt.Key_Return:
            text = self.currentText()
            index = self.findText(text, Qt.MatchExactly | Qt.MatchCaseSensitive)
            self.setCurrentIndex(index)
            self.hidePopup()
            super(ExtendedComboBox, self).keyPressEvent(e)
        else:
            super(ExtendedComboBox, self).keyPressEvent(e)


class SelectBox(ExtendedComboBox):
    def __init__(self, parent=None, options=[], flag="", index=0, onChanged=None):
        super().__init__()

        self.parent = parent
        self.index = index
        self.flag = flag
        # self.setMaximumWidth(200)
        # self._data = data
        # self.setObjectName("value_"+data.get("name"))
        self.onChangedEvent = onChanged
        self._init_show_items(options)
        # self._set(data.get("value"))
        # self.setFixedHeight(WIDGET_HEIGHT)

    def setValue(self, value: str = None):
        self._set(value)

    def getValue(self):
        return self._get()

    def _get(self):
        return self.itemData(self.currentIndex()) or None

    def _set(self, value: str = None):
        if not value:
            self.setCurrentIndex(-1)
        else:
            for index in range(self.count()):
                if self.itemData(index) == value:
                    self.setCurrentIndex(index)
                    break

    def _init_show_items(self, data):
        self.clear()
        items = []
        if isinstance(data, list):
            items = data
        elif isinstance(data, type(lambda x: x)):
            items = data()

        for item in items:
            self.addItem(item.get("title", ""), item.get("value"))
        self.setCurrentIndex(-1)
        self.currentIndexChanged.connect(self.onChanged)
        self.placeholderText = "请选择选项"

    def updateItem(self, data):
        items = []
        if isinstance(data, list):
            items = data
        elif isinstance(data, type(lambda x: x)):
            items = data()
        self.clear()
        for item in items:
            self.addItem(item.get("title", ""), item.get("value"))

    def onChanged(self):
        if self.onChangedEvent:
            self.onChangedEvent(self.currentText(), self.index, self.flag)


class EventFilter(QObject):
    def eventFilter(self, event):
        # 检查事件是否为按键事件，并且按键是否为回车键
        if event.type() == QEvent.KeyPress and event.key() == Qt.Key_Return:
            # 返回 True 表示事件已被处理，不再传播
            return True
        # 返回 False 表示事件未被处理，可以继续传播
        return False


class FloatValidatorDelegate(QStyledItemDelegate):
    def __init__(self, parent=None):
        super(FloatValidatorDelegate, self).__init__(parent)
        self.validator = QDoubleValidator(self)

    def createEditor(self, parent, option, index):
        editor = super(FloatValidatorDelegate, self).createEditor(parent, option, index)
        editor.setValidator(self.validator)
        return editor


class FineLine(QFrame):
    def __init__(self, parent=None):
        super(FineLine, self).__init__(parent)
        self.setFrameShape(QFrame.HLine)
        self.setFrameShadow(QFrame.Sunken)

    def paintEvent(self, event):
        painter = QPainter(self)
        color = QColor(255, 255, 255, 127)  # 透明度范围0-255，127为半透明

        painter.setPen(QPen(color, 0.5))  # 设置画笔宽度为0.5像素
        painter.drawLine(0, self.height() / 2, self.width(), self.height() / 2)


class CustomTable(CParamsTable):

    def __init__(self, rows=0, columns=2, parent=None):
        super(CustomTable, self).__init__(rows=rows, columns=columns, parent=parent)
        self.setEditTriggers(QAbstractItemView.DoubleClicked)
        self.verticalHeader().setVisible(True)


class DlgMaterialSetting(DlgModelParams):
    materialSetting_save_signal = pyqtSignal(object)

    def __init__(self, parent=None):
        super(DlgMaterialSetting, self).__init__(parent)
        self.setWindowTitle("材料属性设置")

        self.widgetDict = {}

        self.setMinimumWidth(800)

        topPlyLayers = self.createLayersTable("上铺层", "topPly", 1)
        bottomPlyLayers = self.createLayersTable("下铺层", "bottomPly", 1)
        topRepairPlyLayers = self.createLayersTable("上铺层修补层", "topRepairPly", 1)
        bottomRepairPlyLayers = self.createLayersTable(
            "下铺层修补层", "bottomRepairPly", 1
        )
        bottomFillPlyLayers = self.createLayersTable("下铺层填充层", "bottomFillPly", 1)

        groupBox1 = QGroupBox("蜂窝芯子材料")
        vLayout1 = QVBoxLayout()
        subGridLayout = QGridLayout()

        # print(self.materialList)

        lab1_2 = QLabel("材料名称/牌号")
        # self.widgetDict["honeycombCoreMateial"] = SelectBox(options=self.materialList)
        self.widgetDict["honeycombCoreMateial"] = SelectBox(options=[])
        groupBox1.setSizePolicy(QSizePolicy.Ignored, -1)

        subGridLayout.addWidget(lab1_2, 1, 0)
        subGridLayout.addWidget(self.widgetDict["honeycombCoreMateial"], 1, 1)
        vLayout1.addLayout(subGridLayout)
        groupBox1.setLayout(vLayout1)

        vLayout = QVBoxLayout()
        vLayout.addWidget(groupBox1)

        groupBox2 = QGroupBox("替换芯子材料")
        vLayout2 = QVBoxLayout()
        subGridLayout2 = QGridLayout()

        lab1_3 = QLabel("材料名称/牌号")
        self.widgetDict["replaceHoneycombCoreMateial"] = SelectBox(options=[])
        groupBox2.setSizePolicy(QSizePolicy.Ignored, -1)

        subGridLayout2.addWidget(lab1_3, 1, 0)
        subGridLayout2.addWidget(self.widgetDict["replaceHoneycombCoreMateial"], 1, 1)
        vLayout2.addLayout(subGridLayout2)
        groupBox2.setLayout(vLayout2)

        vLayout = QVBoxLayout()
        vLayout.addWidget(groupBox1)
        vLayout.addWidget(groupBox2)

        gridLayout = QGridLayout()
        gridLayout.addWidget(topPlyLayers, 1, 0)
        gridLayout.addWidget(bottomPlyLayers, 1, 1)
        gridLayout.addWidget(topRepairPlyLayers, 2, 0)
        gridLayout.addWidget(bottomRepairPlyLayers, 2, 1)
        gridLayout.addLayout(vLayout, 3, 0)
        gridLayout.addWidget(bottomFillPlyLayers, 3, 1)

        self.vbox.insertLayout(0, gridLayout)

        # self.update_UI(self.paramsModeingData, materialSettingData)

        envs.ipimas_updateParamsodeling = (
            lambda type, *args, **kwargs: self.__update_model(type, *args, **kwargs)
        )
        envs.ipimas_updateMaterialLibrary = (
            lambda *args, **kwargs: self.__libraryChange(*args, **kwargs)
        )

    def init(self, data, otherData, opt):

        self.materialList = transform(opt)
        self.widgetDict["honeycombCoreMateial"].updateItem(self.materialList)
        self.widgetDict["honeycombCoreMateial"].setCurrentIndex(-1)

        self.widgetDict["replaceHoneycombCoreMateial"].updateItem(self.materialList)
        self.widgetDict["replaceHoneycombCoreMateial"].setCurrentIndex(-1)

        self.update_UI(otherData, data)

    def __libraryChange(self, *args, **kwargs):
        if self.isVisible():
            QTimer.singleShot(500, self.delayed_action)

    def delayed_action(self):
        MBox.warning("材料库已更新，请重新打开材料属性设置窗口以获取最新数据！")

    def __update_model(self, data, *args, **kwargs):
        if self.isVisible():
            self.paramsModeingData = {}
            for key, value in data.items():
                self.paramsModeingData[util_key_map.valueMap.get(key) or ""] = value

            if self.paramsModeingData.get("damageType") != "贯穿式损伤":
                self.widgetDict["bottomRepairPlyTable"].setEnabled(False)
                self.widgetDict["bottomFillPlyTable"].setEnabled(False)
            else:
                self.widgetDict["bottomRepairPlyTable"].setEnabled(True)
                self.widgetDict["bottomFillPlyTable"].setEnabled(True)
            for v, tableData in self.paramsModeingData.items():
                if (
                    v == "topPlyTable"
                    or v == "bottomPlyTable"
                    or v == "topRepairPlyTable"
                    or v == "bottomRepairPlyTable"
                ):
                    table = self.widgetDict[v]
                    # if v == "bottomPlyTable":
                    #     table = self.widgetDict["bottomFillPlyTable"]
                    try:
                        num_rows = int(len(tableData))
                        table.setRowCount(num_rows)
                        table.set_columns_editable()
                    except ValueError:
                        table.setRowCount(0)
                        table.set_columns_editable()
                    for row in range(table.rowCount()):
                        for column in range(table.columnCount()):
                            if column == 0:
                                wrapWidget = table.cellWidget(row, column)
                                if not wrapWidget:
                                    combo = SelectBox(options=self.materialList)
                                    layout = QVBoxLayout()
                                    layout.addWidget(combo)
                                    cell_widget = QWidget()
                                    cell_widget.setLayout(layout)
                                    table.setCellWidget(row, column, cell_widget)
                    if v == "bottomPlyTable":
                        table = self.widgetDict["bottomFillPlyTable"]
                        try:
                            num_rows = int(len(tableData))
                            table.setRowCount(num_rows)
                            table.set_columns_editable()
                        except ValueError:
                            table.setRowCount(0)
                            table.set_columns_editable()
                        for row in range(table.rowCount()):
                            for column in range(table.columnCount()):
                                if column == 0:
                                    wrapWidget = table.cellWidget(row, column)
                                    if not wrapWidget:
                                        combo = SelectBox(options=self.materialList)
                                        layout = QVBoxLayout()
                                        layout.addWidget(combo)
                                        cell_widget = QWidget()
                                        cell_widget.setLayout(layout)
                                        table.setCellWidget(row, column, cell_widget)

                    table.resizeRowsToContents()
            if "bottomRepairPlyTable" not in self.paramsModeingData:
                self.widgetDict["bottomRepairPlyTable"].setRowCount(0)

    def update_UI(self, data, fillData):

        res = util_key_map.convertKey(fillData, 0)

        self.paramsModeingData = {}
        for key, value in data.items():
            self.paramsModeingData[util_key_map.valueMap.get(key) or ""] = value

        if self.paramsModeingData.get("damageType") != "贯穿式损伤":
            self.widgetDict["bottomRepairPlyTable"].setEnabled(False)
            self.widgetDict["bottomFillPlyTable"].setEnabled(False)
        else:
            self.widgetDict["bottomRepairPlyTable"].setEnabled(True)
            self.widgetDict["bottomFillPlyTable"].setEnabled(True)

        for v, tableData in self.paramsModeingData.items():
            if (
                v == "topPlyTable"
                or v == "bottomPlyTable"
                or v == "topRepairPlyTable"
                or v == "bottomRepairPlyTable"
            ):
                self.createTableRow(v, tableData)
            if v == "bottomPlyTable":
                self.createTableRow("bottomFillPlyTable", tableData)

        for v, tableData in res.items():
            if v == "honeycombCore":
                value = {
                    "材料名称": tableData.get("材料名称"),
                    "材料类型": tableData.get("材料类型"),
                }
                self.widgetDict[f"{v}Mateial"].setValue(value)
            elif v == "replaceHoneycombCore":
                value = {
                    "材料名称": tableData.get("材料名称"),
                    "材料类型": tableData.get("材料类型"),
                }
                self.widgetDict[f"{v}Mateial"].setValue(value)
            else:
                self.fillTableData(v, tableData)

    def createTableRow(self, v, tableData):
        table = self.widgetDict[v]
        # table.setColumnCount(2)
        column_count = table.columnCount()
        table.setRowCount(len(tableData))
        for rowIdx, rowData in enumerate(tableData):
            for colIdx in range(column_count):
                if colIdx == 0:
                    combo = SelectBox(options=self.materialList)
                    layout = QVBoxLayout()
                    layout.addWidget(combo)
                    cell_widget = QWidget()
                    cell_widget.setLayout(layout)
                    table.setCellWidget(rowIdx, colIdx, cell_widget)
                else:
                    table.setItem(rowIdx, colIdx, QTableWidgetItem(""))

            table.resizeRowsToContents()

    def fillTableData(self, v, data):
        table = self.widgetDict[v]
        for row in range(table.rowCount()):
            if len(data) - 1 < row:
                continue
            for column in range(table.columnCount()):
                if column == 0:
                    wrapWidget = table.cellWidget(row, column)
                    wrapLayout = wrapWidget.layout()
                    selectBox = wrapLayout.itemAt(0).widget()
                    material = data[row].get("material") or {}
                    if material:
                        # print(material.get("材料名称"))
                        value = {
                            "材料名称": material.get("材料名称"),
                            "材料类型": material.get("材料类型"),
                        }
                        selectBox.setValue(value)
                else:
                    item = QTableWidgetItem(str(data[row].get("Angle") or ""))
                    item.setTextAlignment(Qt.AlignCenter)
                    table.setItem(row, column, item)

    def createLayersTable(self, title, name, type=0):
        groupBox = QGroupBox(title)
        layersLayout = QVBoxLayout()
        if type == 1:
            table = CustomTable(rows=1, columns=2)
            table.setItemDelegateForColumn(1, FloatValidatorDelegate(table))
            table.setHorizontalHeaderLabels(["材料名称/牌号", "铺层角度"])
            table.horizontalHeader().setSectionResizeMode(
                1, QHeaderView.Fixed
            )  # 第一列固定
            table.setColumnWidth(1, 100)
        else:
            table = CustomTable(rows=1, columns=1)
            # table.setMaximumHeight(90)
            # table.setItemDelegateForColumn(0, FloatValidatorDelegate(table))
            table.setHorizontalHeaderLabels(["材料"])
        self.widgetDict[f"{name}Table"] = table
        layersLayout.addWidget(table)
        groupBox.setLayout(layersLayout)

        # 计算前三行的高度
        # total_height = 0
        # total_height = table.rowHeight(0) * 3
        # horizontal_header_height = table.horizontalHeader().height()
        # # table.resize(-1, total_height + horizontal_header_height)
        # # table.setFixedHeight(total_height + horizontal_header_height)
        # table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
        # table.setMinimumHeight(total_height + horizontal_header_height)
        table.removeRow(0)  # 删除第一行

        return groupBox

    # def getTableDict(self, table, valueList, descriptionList, type):
    #     for i in range(table.rowCount()):
    #         rowDict = {}
    #         typeList = ["铺层名称", "厚度"]
    #         for j in range(table.columnCount()):

    #             item = table.item(i, j)
    #             if type == 1:
    #                 if j == 1:
    #                     rowDict[typeList[j]] = float(item.text()) if item.text() is not None else None
    #                 else:
    #                     rowDict[typeList[j]] = item.text()
    #             elif type == 0:
    #                 rowDict['厚度'] = float(item.text()) if item.text() is not None else None
    #         valueList.append(rowDict)
    #         descriptionList.append(rowDict)
    #     return valueList

    @pyqtSlot()
    def on_pBtnOK_clicked(self):
        self.pBtnOK.setFocus()
        data = {}
        # descriptData = {}
        data["topPlyTable"] = self.getTableValue(self.widgetDict["topPlyTable"])
        data["bottomPlyTable"] = self.getTableValue(self.widgetDict["bottomPlyTable"])
        data["topRepairPlyTable"] = self.getTableValue(
            self.widgetDict["topRepairPlyTable"]
        )
        data["honeycombCore"] = {
            "mateial": self.widgetDict["honeycombCoreMateial"].getValue()
        }

        data["replaceHoneycombCore"] = {
            "mateial": self.widgetDict["replaceHoneycombCoreMateial"].getValue()
        }

        if self.paramsModeingData.get("damageType") == "贯穿式损伤":
            data["bottomRepairPlyTable"] = self.getTableValue(
                self.widgetDict["bottomRepairPlyTable"]
            )
            data["bottomFillPlyTable"] = self.getTableValue(
                self.widgetDict["bottomFillPlyTable"]
            )

        for v, itemList in data.items():
            if isinstance(itemList, list):
                for item in itemList:
                    if item.get("material"):
                        material = item.get("material")
                        mType = material.get("type")
                        if mType == "Laminate":
                            for itemData in self.compositePlyData:
                                if itemData.get("材料名称") == material.get("材料名称"):
                                    item["material"] = itemData
                        elif mType == "Honeycomb":
                            for itemData in self.honeycombCoreData:
                                if itemData.get("材料名称") == material.get("材料名称"):
                                    item["material"] = itemData
                        elif mType == "胶层":
                            for itemData in self.adhesiveLayerData:
                                if itemData.get("材料名称") == material.get("材料名称"):
                                    item["material"] = itemData
            elif isinstance(itemList, dict):
                if itemList.get("material"):
                    material = itemList.get("material")
                    mType = material.get("type")
                    if mType == "Laminate":
                        for itemData in self.compositePlyData:
                            if itemData.get("材料名称") == material.get("材料名称"):
                                itemList["material"] = itemData
                    elif mType == "Honeycomb":
                        for itemData in self.honeycombCoreData:
                            if itemData.get("材料名称") == material.get("材料名称"):
                                itemList["material"] = itemData
                    elif mType == "胶层":
                        for itemData in self.adhesiveLayerData:
                            if itemData.get("材料名称") == material.get("材料名称"):
                                itemList["material"] = itemData

        if not self.check_empty_values(data["topPlyTable"]):
            return MBox.warning("请补全上铺层数据")
        if not self.check_empty_values(data["bottomPlyTable"]):
            return MBox.warning("请补全下铺层数据")
        if not self.check_empty_values(data["topRepairPlyTable"]):
            return MBox.warning("请补全上铺层修补层数据")
        if not self.widgetDict["honeycombCoreMateial"].getValue():
            return MBox.warning("请补全蜂窝芯子数据")
        if not self.widgetDict["replaceHoneycombCoreMateial"].getValue():
            return MBox.warning("请补全替换芯子数据")

        if self.paramsModeingData.get("damageType") == "贯穿式损伤":
            if not self.check_empty_values(data["bottomRepairPlyTable"]):
                return MBox.warning("请补全下铺层修补层数据")
            if not self.check_empty_values(data["bottomFillPlyTable"]):
                return MBox.warning("请补全下铺层填充层数据")
        # if (
        #     self.paramsModeingData.get("damageType") == "贯穿式损伤"
        #     or self.paramsModeingData.get("damageType") == "蜂窝芯子损伤"
        # ) and not self.widgetDict["honeycombCoreRepairMateial"].getValue():
        #     return MBox.warning("请补全蜂窝芯子修补层数据")

        # if (self.component.gridWidgets['damageType'].currentText() == "贯穿式损伤") and not self.check_empty_values(descriptionRes['下铺层修补层']) :
        #     return MBox.warning("请补全下铺层修补层数据")

        # print(descriptData)

        # file2 = "data/ipimas/uis/MaterialSetting2.json"
        # Utils.write_json(file2, data)

        if "honeycombCore" in data:
            data["honeycombCore"] = data["honeycombCore"].get("mateial")

        if "replaceHoneycombCore" in data:
            data["replaceHoneycombCore"] = data["replaceHoneycombCore"].get("mateial")

        res = util_key_map.convertKey(data, 1)

        file = "data/ipimas/uis/MaterialSetting.json"
        Utils.write_json(file, res)
        self.close()
        # filtered_data = remove_id(descriptData)

        # # if "蜂窝芯子修补层" in filtered_data:
        # #     filtered_data["蜂窝芯子修补层"] = filtered_data["蜂窝芯子修补层"].get(
        # #         "材料"
        # #     )

        self.materialSetting_save_signal.emit(res)

    def getTableValue(self, table):
        data = []
        # descriptData = []
        for row in range(table.rowCount()):
            rowData = {}
            # descriptRowData = {}
            for column in range(table.columnCount()):
                if column < 1:
                    wrapWidget = table.cellWidget(row, column)
                    wrapLayout = wrapWidget.layout()
                    selectBox = wrapLayout.itemAt(0).widget()
                    # if column == 0:
                    rowData["material"] = selectBox.getValue()
                    # descriptRowData["材料"] = selectBox.getValue()
                    # elif column == 1:
                    #     # rowData['material'] = 'selectBox.getValue()'
                    #     rowData['material'] = selectBox.getValue()
                else:
                    item = table.item(row, column)
                    if item is not None:
                        # print("item.text()=", item.text())
                        rowData["Angle"] = toFloat(item.text())
                        # descriptRowData["铺层角度"] = toFloat(item.text())
            data.append(rowData)
            # descriptData.append(descriptRowData)
        # return [data, descriptData]
        return data
        # print(data)

    def setTableSelect(self, table):
        # data = []
        # descriptData = []
        for row in range(table.rowCount()):
            # rowData = {}
            # descriptRowData = {}
            for column in range(table.columnCount()):
                if column == 0:
                    wrapWidget = table.cellWidget(row, column)
                    wrapLayout = wrapWidget.layout()
                    selectBox = wrapLayout.itemAt(0).widget()
                    selectBox.updateItem(self.materialList)
                    # if column == 0:
                    # rowData['material'] = selectBox.getValue()
                    # descriptRowData['材料'] = selectBox.getValue()
                    # elif column == 1:
                    #     # rowData['material'] = 'selectBox.getValue()'
                    #     rowData['material'] = selectBox.getValue()

        #     data.append(rowData)
        #     descriptData.append(descriptRowData)
        # return [data,descriptData]

    def check_empty_values(self, data_list):
        for item in data_list:
            for key, value in item.items():
                if value == "" or value is None:
                    return False
                #     print(f"属性 '{key}' 的值为空或空字符串")
                # else:
                #     print(f"属性 '{key}' 的值为 '{value}'")
        return True

    def closeEvent(self, event):
        DlgMaterialSetting._shown = False  # 使用类名访问类属性
        DlgMaterialSetting._instance = None  # 清除实例引用
        event.accept()


def remove_id(data):
    if isinstance(data, dict):
        return {k: remove_id(v) for k, v in data.items() if k != "id"}
    elif isinstance(data, list):
        return [remove_id(item) for item in data]
    else:
        return data


def toFloat(value):
    try:
        return float(value)
    except ValueError:
        return None


def transform(data):

    result = []
    for item in data:
        if item:
            result.append(
                {
                    "value": {
                        "材料名称": item.get("材料名称"),
                        "材料类型": "Laminate",
                    },
                    "title": item.get("材料名称"),
                }
            )
    return result


def transform2(data1, data2, data3):
    # print("data1=", data1)
    # print("data2=", data2)
    result1 = []
    result2 = []
    result3 = []
    for item in data1:
        # 获取字典的第一个键作为title
        title_key = next(iter(item), None)
        if title_key:
            result1.append(
                {
                    "value": {
                        "材料名称": item["材料名称"],
                        "材料类型": "Laminate",
                    },
                    "title": item[title_key],
                }
            )
        for item in data2:
            # 获取字典的第一个键作为title
            title_key = next(iter(item), None)
            if title_key:
                result2.append(
                    {
                        "value": {
                            "材料名称": item["材料名称"],
                            "材料类型": "Honeycomb",
                        },
                        "title": item[title_key],
                    }
                )
        for item in data3:
            # 获取字典的第一个键作为title
            title_key = next(iter(item), None)
            if title_key:
                result3.append(
                    {
                        "value": {
                            "材料名称": item["材料名称"],
                            "材料类型": "胶层",
                        },
                        "title": item[title_key],
                        # "title": "胶层-" + item[title_key]
                    }
                )
        return result1 + result2 + result3
        # return result1
